﻿using System;
using System.IO;
using System.Text;
using Zinnia.Lite.Exceptions;
using Zinnia.Lite.Untilty;

namespace Zinnia.Lite.Core.Imp
{
    /// <summary>
    /// 文件服务实现类
    /// </summary>
    internal class FileService : IFileService
    {
        private string _fileName;
        private Encoding _encode;
        private readonly IoLockService _ioLock = new IoLockService();
        //为避免在写文件的过程将writer释放
        private readonly object _objLock = new object();
        public FileService()
        {
            _encode = Encoding.Default;
        }
        /// <summary>
        /// 获取根目录
        /// </summary>
        /// <returns>~/</returns>
        private string GetRootPath()
        {
            return DirectoryHelper.GetApplicationRootPath();
        }

        private void Init(string relativePath, Encoding encode)
        {
            _fileName = GetRootPath() + relativePath;
            _encode = encode ?? Encoding.Default;
        }

        public string ReadFileText(string relativePath, Encoding encode)
        {
            string result;
            try
            {
                if (!_ioLock.TryEnterReadLock())
                {
                    throw new LiteException("其他人正在使用中...");
                }
                Init(relativePath, encode);
                result = LocalCacheHelper.Instance.GetCacheOjbect<string>(_fileName);
                if (!string.IsNullOrWhiteSpace(result)) return result;
                using (FileStream fStream = new FileStream(_fileName, FileMode.Open))
                {
                    StreamReader reader = new StreamReader(fStream, _encode);
                    reader.BaseStream.Seek(0, SeekOrigin.Begin); //从数据流中读取每一行
                    result = reader.ReadToEnd();
                }
                LocalCacheHelper.Instance.Add<string>(result, _fileName, _fileName);
            }
            catch (Exception ex)
            {
                throw new LiteException("写入文件时发生异常" + ex);
            }
            finally
            {
                try
                {
                    _ioLock.ExitReadLock();
                }
                catch
                {
                }
            }
            return result;
        }

        public void Write(string content, string relativePath, Encoding encode)
        {
            try
            {
                if (!_ioLock.TryEnterWriteLock())
                {
                    throw new LiteException("其他人正在使用中...");
                }
                Init(relativePath, encode);
                lock (_objLock)
                {
                    using (StreamWriter writer = new StreamWriter(_fileName))
                    {
                        writer.Write(content);
                        writer.Close();
                    }
                }
            }
            catch (Exception ex)
            {
                throw new LiteException("读取文件时发生异常" + ex);
            }
            finally
            {
                try
                {
                    _ioLock.ExitWriteLock();
                }
                catch
                {
                }
            }
        }
    }
}
